package archer.application.core.service.system;

import static archer.application.core.ArcherApplicationCoreModule.*;

import archer.application.core.constant.Constant;
import archer.application.core.entity.system.Menu;
import archer.application.core.entity.system.Role;
import archer.application.core.entity.system.RoleMenuRel;
import archer.application.core.entity.system.UserRoleRel;
import archer.application.core.entity.user.Staff;
import archer.application.core.service.BaseService;
import archer.application.core.service.user.UserService;
import archer.framework.common.repository.condition.QueryCondition;
import archer.framework.protocol.result.ExecuteResult;
import com.avaje.ebean.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 后端系统用户Service
 *
 * @author christ
 * @date 2016/6/7
 */
@Service
public class StaffService extends BaseService {

    private static String type = Constant.UserType.STAFF;

    protected final static String ALIAS_MENU = "menu";

    protected final static String ALIAS_ROLE_MENU = "rm";

    @Autowired
    UserService userService;

    /**
     * 登录
     *
     * @param loginName
     * @param password
     * @return
     */
    public ExecuteResult login(String loginName, String password) {

        if (isEmpty(loginName)) {
            throwParamNullException("登录名不能为空");
        }

        if (isEmpty(password)) {
            throwParamNullException("密码不能为空");
        }

        return userService.loginNameLogin(loginName, password, type);
    }

    /**
     * 退出
     *
     * @return
     */
    public ExecuteResult logout() {

        return userService.logout();
    }


    /**
     * 新增/保存用户
     *
     * @param staff
     * @return
     */
    public ExecuteResult store(Staff staff) {

        if (isEmpty(staff.getLoginName())) {
            throwParamNullException("用户名不能为空");
        }

        if (isEmpty(staff.getPassword())) {
            throwParamNullException("密码不能为空");
        }

        if (isNotEmpty(staff.getMobile()) && isNotMoblie(staff.getMobile())) {
            throwParamNullException("手机号格式不正确");
        }

        if (isNotEmpty(staff.getEmail()) && isNotEmail(staff.getEmail())) {
            throwParamNullException("邮箱格式不正确");
        }

        if (isNotEmpty(staff.getId())) {

            Staff stored = Staff.find.byId(staff.getId());

            if (isNotEmpty(stored) && isY(stored.getSysData()) && !stored.getLoginName().equals(staff.getLoginName())) {

                throwAccessDeniedException("系统内置数据的用户名不能修改");
            }
        }

        if (staff.duplicated("loginName", asMap("type", type))) {
            throwParamInvalidateException("该用户名已注册");
        }

        if (isNotEmpty(staff.getMobile()) && staff.duplicated("mobile", asMap("type", type))) {
            throwParamInvalidateException("该手机号已注册");
        }

        if (isNotEmpty(staff.getEmail()) && staff.duplicated("email", asMap("type", type))) {
            throwParamInvalidateException("该邮箱已注册");
        }

        return success(staff.storeAndQuery());
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public ExecuteResult delete(String id) {

        if (isEmpty(id)) {

            throwParamNullException("用户不能为空");
        }

        Staff staff = Staff.find.byId(id);

        if (isNotEmpty(staff)) {

            if (isY(staff.getSysData())) {

                throwAccessDeniedException("系统内置数据不能删除");
            }

            //删除用户角色表
            delete(
                    UserRoleRel.find
                            .query()
                            .where()
                            .eq("staff.id", id)
                            .findList()
            );

            //删除用户表
            staff.logicalDelete();
        }

        return success();
    }

    public ExecuteResult deleteAll(List<String> ids) {

        for (String each : ids) {
            this.delete(each);
        }

        return success();
    }

    /**
     * 分页查找所有用户
     *
     * @param queryCondition
     * @return
     */
    public ExecuteResult findPagedList(QueryCondition queryCondition) {

        return success(super.findPagedList(Staff.find.query(), queryCondition));
    }


    /**
     * 查询某个用户的菜单列表
     *
     * @param id
     * @return
     */
    public ExecuteResult findMenuList(String id) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }
        Staff staff = Staff.find.byId(id);

        if (isNotEmpty(staff)) {

            // admin用户具有所有菜单权限
            if (isY(staff.getSysData()) && adminUserLoginName.equals(staff.getLoginName())) {

                return success(Menu.find.query().where().orderBy("sort").findList());
            }

            return success(
                    Menu.find.exists(ALIAS_MENU, getStaffMenuExistsQuery(id, ALIAS_MENU)).orderBy("sort").findList()
            );
        }

        return success(emptyList());
    }

    /**
     * 查询某个用户的菜单树
     *
     * @param id
     * @return
     */
    public ExecuteResult findMyDisplayMenuList(String id) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }
        Staff staff = Staff.find.byId(id);
        if (isNotEmpty(staff)) {

            // admin用户具有所有菜单权限
            if (isY(staff.getSysData()) && adminUserLoginName.equals(staff.getLoginName())) {

                return success(Menu.find.query().where().eq("display", Constant.EntityDefault.Y).orderBy("sort").findList());
            }

            return success(
                    Menu.find.exists(ALIAS_MENU, getStaffMenuExistsQuery(id, ALIAS_MENU)).where().eq("display", Constant.EntityDefault.Y).orderBy("sort").findList()
            );
        }

        return success(emptyList());
    }

    /**
     * 构造用户菜单exists子查询
     *
     * @param id
     * @param mainAlias 主表别名
     * @return
     */
    private Query getStaffMenuExistsQuery(String id, String mainAlias) {
        return RoleMenuRel.find.existsSubQuery(ALIAS_ROLE_MENU,
                template("${aliasRoleMenu}.menu_id=${aliasMenu}.id")
                        .bind(asMap("aliasRoleMenu", ALIAS_ROLE_MENU, "aliasMenu", ALIAS_MENU))
                        .toString()
        ).where().eq("role.userRoleRels.staff.id", id).query();
    }

    /**
     * 查询某个用户的角色列表
     *
     * @param id
     * @return
     */
    public ExecuteResult findRoleList(String id) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }

        //返回角色列表
        return success(
                Role.find.query()
                        .where()
                        .eq("userRoleRels.staff.id", id)
                        .findList()
        );
    }

}

